跳轉到

5.1 Transformer — Attention Is All You Need

前言

Transformer 完全基於 Attention 注意力機制的架構。Attention 原先是被應用在 RNN,之後 Google 所提出的 Transformer 保留了原先 Attention 的優勢並移除了 RNN 的架構。Transformer 是一個蠻新的模型,最先由 2017 年被 Google 所提出一篇叫 Attention is all you need 的論文。

Transformer 是一種 Seq2seq 的模型,他有一個 Encoder 和 Decoder 並且非常適合做機器翻譯。另外在 Transformer 中拋棄了 RNN 循環神經網路的架構。Transformer 僅保留了 Attention 機制以及全連接層網路,實驗結果並優於 RNN+Attemtion 的架構。目前最新的機器翻譯研究已經很少人用 RNN 模型了,當今業界大多使用 Transformer + Bert 模型。

  • Transformer is a Seq2Seq model.
  • Transformer is not RNN.
  • Purely based attention and dense layers.
  • Higher accuracy than RNNs on large datasets.

重新審視 Attention + RNN

這裡來思考一個問題。當我們把 RNN 去掉只保留 Attention,僅利用 Attention 搭建一個神經網路用來取代 RNN。那我們該怎麼做呢?接下來我們會來詳細討論,從零開始基於 Attention 搭建一個神經網路的整個流程。首先在本篇文章我們先將之前學過的 RNN + Attention 開始入手,再抽取掉 RNN 保留 Attention。然後搭建一個 Attention 與 Self-Attention 網路層。下一篇文章會再將這些概念組裝起來,搭建一個深度的 Seq2seq 模型。搭出來的模型就是當今最紅的 Transformer。

Attention for Seq2Seq Model

RNN 的 Attention Q、K、V 計算

前篇文章有提到 RNN 模型的進化,最終使用 Attention 機制來改善 RNN Seq2seq 的模型。所謂的 Seq2seq 是指有一個 Encoder 和一個 Decoder。Encoder 的輸入是有 m 個時間點的輸入X1~Xm,每個一個輸入都是經過編碼過後的向量。Encoder 把這些輸入的訊息壓縮到隱藏狀態向量 h 中,其最後一個狀態 hm 是看過所有的輸入後所壓縮的訊息。Decoder 所做的事情取決於你的任務是什麼,例如文字生成器。在 Decoder 中會依序產生出狀態 s,每個時間點會根據狀態生成一個文字。我們在把輸出的文字作為下一次的輸入x,如果有 Attention 機制的話還需要計算 context vector(c)。每當計算出一個狀態 s 就要計算一次 c。

context vector(c) 計算方式是,首先將 Decoder 當前狀態 sj 與 Encoder 所有狀態 h1~hm 做對比並用 align() 函數計算彼此間的相關性。把算出的 𝛼ij 作為注意力的分數。 每計算一次 context vector 就要計算出 m 個分數,其表示 𝛼1j ~ 𝛼mj

每一個 𝛼 對應一個狀態 h,以下我們具體的來看一下分數 𝛼 是如何被計算出來的。分數的計算是 hi 和 sj 的函數,首先我們必須計算 Q 和 K。把向量 hi 乘上一個矩陣 WK 得到 ki。 另外把向量 sj 乘上一個矩陣 WQ 得到 qj。這裡的矩陣 WK 與 WQ 是 align() 函數中可以學習的權重,必須經由訓練資料中去學習的。我們必須把 sj 這一個向量與 Encoder 中的所有 h 去計算對比。有 m 個 h 向量因此會有 m 個 k,我們可以將 k1~km 組成一個 K 矩陣。我們可以發現圖中綠色的 ki 向量為 K 的每一行(col)。

計算每個分數需要將 K 進行轉置並與 qj 進行矩陣相乘的運算。輸出會是一個 m 維的向量。最後再使用一個 Softmax 函數將這些輸出的數值映射到 0~1 之間,並且這 m 個數值加總必為 1。此時的 𝛼1j~ 𝛼mj 為最終 qj 所對輸入有感興趣的地方的分數。

剛才已經將 Decoder 狀態 sj 還有 Encoder 狀態 hi 分別做線性轉換,得到一組向量 qj(Query) 與 m 個 ki(Key)。我們拿一個 qj 向量去對比所有 Key(K),算出 m 個分數,這 m 個 𝛼 分數表示了 Query 與每一個 Key 的匹配程度。其匹配程度越高 𝛼 分數越大,同時也代表著模型需要更關注這些內容。除此之外我們還需要計算 Value,將 hi 乘上一個矩陣 WV 上 就能得到 v1~vm。這些合併起來就能用 V 表示,另外這裡的 WV 也是可以透過機器學習的。

實際範例 Attention for Seq2Seq Model

剛剛已經講了 Q、K、V 這三種向量 在 RNN 架構中是如何被計算出來的。我們再回過頭看一下這個例子。首先我們先把 Decoder 目前狀態 sj 乘上一個 WQ 得到 qj

然後把 Encoder 所有 m 個狀態 h1~hm 乘上 WK 映射到 Key 向量。

用矩陣 K 與向量 qj 計算出 m 維的分數向量。a1j~amj 對應每個 Encoder 的 h 向量。最後還要經過一個 Softmax() 即代表對輸入 x1~xm 所需要關注的分數。

接下來計算 Value 向量 vi,我們拿 Encoder 第 i 個狀態向量 hi 與一個權重 WV 做一個線性轉換得到 vi。每一個 vi 對應一個隱藏狀態 h。最終我們將會得到 m 個 𝛂 與 v,並做加權平均得到一組新的 context vector(c)。cj 等於 𝛼1j 乘上 v1 一直加到 𝛼mj 乘上 vm。 這種計算分數 𝛼 和 context vector(c) 的方法就是 Transformer 用的機制。

Attention without RNN

這一個部分我們來討論捨棄 RNN 只保留 Attention 的 Transformer,並得到一個 Attention 與 Self-Attention Layer。

Attention Layer

首先我們先設計一個 Attention Layer 用於 Seq2seq 模型,一樣包含一個 Encoder 與一個 Decoder。Encoder 的輸入向量是 x1~xm。Decoder 的輸入是 x’1~x’t。

這裡我們捨去 RNN 只用 Attention。首先拿 Encoder 的輸入 x1~xm 來計算 Key 與 Value 向量。於是 x1 就被映射成 k1 與 v1,x2 就被映射成 k2 與 v2,依此類推我們就得到 m 組的 k 和 v 向量。

然後把 Decoder 的輸入 x’1~x’t 做一個線性轉換乘上 Wq 得到 Query。若 Decoder 有 t 個輸入向量,則將會有 t 個 query q1~qt。注意一下目前為止總共出現了三個 W 矩陣,分別為 Encoder 中的 WK 和 WV 與 Decoder 中的 WQ。這些權重都是可以經由訓練資料進行學習的權重。

現在開始計算分數𝛂,拿取 Decoder 中的第一個 q1 與所有 Encoder 中 m 個 k 向量做對比。透過 Scaled dot product 計算出每一個輸入的分數,也就是所謂的 Attention 關聯強度。我們將會得到 m 維的向量 𝛂1(𝛂11~𝛂m1),裏面代表著每個相對應輸入的注意力程度。

然後再計算 context vector c1,需要用到分數向量 𝜶1 與所有 m 個 value 向量進行加權和。又可以寫成 V𝜶1

接下來重複上述步驟可以得到所有 context vector,每一個 c 對應一個 x’。

假設有七個輸出將會有七個 context vector,分別為 c1~c7 為最終的輸出。並且可以用 C 表示這些向量。想要計算一個向量 cj 要用到所有的 Q、K、V。所以 c2 依賴於 x’2 以及 Encoder 中所有的輸入,並透過注意力分數來取捨資訊。

我們把 Attention layer 稱之為函數 Attn(),輸入是分別是 Encoder 的 x1~xm (X)以及 Decoder 的 x’1~x’t (X’)。除此之外 Attention layer 有三個要學習的權重矩陣 WQ、WK、WV。最後 Attention layer 的輸出是 c1~ct (C) 共 t 個向量。因此我們可以總結 Attention layer 有兩個輸入 X 與 X‘,以及一個輸出 C,每一個 c 向量對應一個 x’ 向量。

Self-Attention without RNN

剛才我們將 Seq2seq 模型剔除了 RNN,並採用 Attention Layer 替代。接下來要來了解 Self-Attention Layer。基本上原理完全一模一樣,我們可以使用 Self-Attention 來取代 RNN。

Self-Attention Layer

Self-Attention Layer 並非 Seq2seq 它僅有一個輸入序列,同時可以使用 Attn() 函數表示。此函數跟先前提的方法一模一樣,差別在於函數的輸入都是 X。此外輸出的序列是 c1~cm 與輸入 x 的虛列長度是一樣的都是 m,每一個 c 向量都對應一個 x 向量。但是必須注意,舉例來說 c2 並非只依賴於 x2,他是依賴於 x1~xm 也就是每個輸入都會考慮過才算出 c2

Self-Attention Layer 的原理跟 Attention Layer 完全一模一樣。只差別於輸入不同,在 Self-Attention 中僅有一個輸入序列 x1~xm。第一步是做三種轉換將 xi 映射到 qi、ki、vi 並得到三個向量。權重矩陣依然是 WQ、WK、WV 對輸入 x 做線性轉換。

每個 x 輸入都做了線性轉換後會得到 q、k、v 三個向量。接下來再計算分數向量 𝛼 ,公式還是一樣的。我們將矩陣 K(k1~km) 轉置乘上 qj 向量然後做 Softmax 得到 m 維向量 𝛼j。我們可以從圖中的例子看到 𝛼1 依賴於 q1 以及所有 k 向量 k1~km

依此類推 𝛼2 依賴於 q2 以及所有 k 向量 k1~km。用同樣的公式計算出所有分數向量 𝛼。總共有 m 個 𝛼 向量,此外每個分數向量都是 m 維的。

現在可以開始計算 context vector。 c1 是所有 m 個 v 向量與 𝛼 的加權和。看以下這張圖,c1 依賴於分數向量 𝛼1,以及所有 m 個 v 向量 v1~vm

計算同樣的步驟算出 m 個 c 向量得到 c1~cm。這 m 個 c 向量就是 Self-Attention Layer 的輸出。其中第 j 個輸出 cj 是依賴於矩陣 V、K 以及向量 qj。 因為所有的 cj 依賴於所有的 K 與 V,所以 cj 依賴於所有 m 個 x 向量 x1~xm。下圖中每個輸入 xi 位置上都對應一個輸出 ci,每個 ci 並非只關注自己的 xi 而是依賴於所有的 x。只要改變任何一個 x 所有的 ci 都會發生變化。

我們已經學習了 Self-Attention Layer 的運作機制。輸入是一個序列 x1~xm,這一個網路曾將有三組權重矩陣分別有 WQ、WK、WV。這三個矩陣能把每個 x 映射到 q、k、v 三個向量。其每一個輸出也是一個序列 c1~cm 共有 m 個向量,每一個 x 位置上都有對應的 c。 Attention 與 Self-Attention 都用 Attn() 這個函數來表示,此函數有兩個輸入矩陣。Attention Layer 的輸入是 X 與 X’ 而 Self-Attention 的輸入是兩個相同的 X。

小結

到目前為止已經說明了 Attention 與 Self-Attention Layer,最後做一個小結。Attention 的想法最初在 2015 年由 Bengio 實驗室所發表的論文中。此篇論文使用 Attention 改進 Seq2seq 模型,後來大家發現 Attention 並不局限於 Seq2seq 模型,而是可以使用在所有的 RNN 上。如果僅有一個 RNN 網路,那麼 Attention 就稱為 Self-Attention。Self-Attention 這篇論文於 2016 年被發表,再後來 Google 於 2017 年發表的 Attention Is All You Need 表示根本不需要使用到 RNN。直接單獨使用 Attention 效果會更好。另外此篇論文中提出了 Transformer 模型架構,也就是下篇文章將提到的部分。

本篇文章內容來至於線上課程 CS583: Deep Learning

Reference

[1] Bahdanau, Cho, & Bengio. Neural machine translation by jointly learning to align and translate. In ICLR, 2015.

[2] Cheng, Dong, & Lapata. Long Short-Term Memory-Networks for Machine Reading. In EMNLP, 2016.

[3] Vaswani et al. Attention Is All You Need. In NIPS, 2017.

Transformer模型(1/2): 剝離RNN,保留Attention

簡報